﻿// This File is part of Innovation Foundry's "QualityHelper Project"
//
// Copyright  2009 Innovation Foundry Pty Ltd
// All rights reserved
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA  02110-1301 USA
// or alternatively it may be downloaded from <http://www.gnu.org/licenses/>.

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Collections.Generic;

namespace InnovationFoundry.QualityHelper.Utilities
{

    public interface IHasID 
    {
        object ID { get;}
    }

    public class ObservableCollectionWithID<T> : ObservableCollection<T> where T : IHasID
    {
        public T GetFirstItemByID(object id)
        {
            //T temp = default(T);
            foreach (var obj in this)
            {
                if (obj.ID == id || (id != null && id.Equals(obj.ID)))
                {
                    return obj;
                }
            }
            return default(T);
        }

        public int GetFirstItemIndexByID(object id)
        {
            //T temp = default(T);
            for (int i = 0; i < this.Count; i++ )
            {
                if (this != null && this[i].ID == id)
                {
                    return i;
                }
            }
            return -1;
        }

    }


    public class RingBuffer<T> : List<T>
    {
        private int ringLength = 1;

        /// <summary>
        /// Indicates length of ring buffer.
        /// </summary>
        /// <param name="length"></param>
        public RingBuffer(int length) : base(length)
        {
            if (length < 1)
                throw new Exception("Can't allocate a ringbuffer less than 1");
            ringLength = length;
        }

        /// <summary>
        /// Adds an item into the ring buffer.
        /// </summary>
        /// <param name="item"></param>
        public void AddToRing(T item)
        {
            if (this.Contains(item))
                return;
            this.Insert(0, item);
            for (int i = Count - 1; i > ringLength; i--)
                this.RemoveAt(i);
        }

    }


    public class RingBufferObservable<T> : ObservableCollection<T>
    {
        private int ringLength = 1;

        /// <summary>
        /// Indicates length of ring buffer.
        /// </summary>
        /// <param name="length"></param>
        public RingBufferObservable(int length)
        {
            if (length < 1)
                throw new Exception("Can't allocate a ringbuffer less than 1");
            ringLength = length;

        }

        /// <summary>
        /// Adds an item into the ring buffer.
        /// </summary>
        /// <param name="item"></param>
        public void AddToRing(T item)
        {
            if (this.Contains(item))
                return;
            this.Insert(0, item);
            for (int i = Count; i > ringLength; i--)
                this.RemoveAt(i - 1);
        }

    }

    public class RingBufferObservableWithID<T> : ObservableCollectionWithID<T> where T : IHasID
    {
        private int ringLength = 1;

        /// <summary>
        /// Indicates length of ring buffer.
        /// </summary>
        /// <param name="length"></param>
        public RingBufferObservableWithID(int length)
        {
            if (length < 1)
                throw new Exception("Can't allocate a ringbuffer less than 1");
                ringLength = length;

        }

        /// <summary>
        /// Adds an item into the ring buffer.
        /// </summary>
        /// <param name="item"></param>
        public void AddToRing(T item)
        {
            T found = this.GetFirstItemByID(item.ID);
            if (found != null)
            {
                return;
            }
            this.Insert(0, item);
            for (int i = Count; i > ringLength; i--)
                this.RemoveAt(i-1);
        }

    }

}
